package com.tjsinfo.tjsoa.workflow.bo;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.json.JSONObject;
import org.springframework.jdbc.core.RowMapper;

import com.sun.org.apache.regexp.internal.recompile;
import com.tjsinfo.tjsoa.Dao.IHQLDao;
import com.tjsinfo.tjsoa.Dao.IJDBCDao;
import com.tjsinfo.tjsoa.Dao.IQbcDao;
import com.tjsinfo.tjsoa.Dao.ISpringDao;
import com.tjsinfo.tjsoa.common.PaginationSupport;
import com.tjsinfo.tjsoa.common.ToolKit;
import com.tjsinfo.tjsoa.workflow.Taskinstance;
import com.tjsinfo.tjsoa.workflow.WorkFlowTemplate;

public class TaskInstanceBO implements ITaskInstanceBO {
	private IQbcDao qbcDao;
	private IHQLDao hqlDao;
	private ISpringDao springDao;
	
	
	
	public ISpringDao getSpringDao() {
		return springDao;
	}

	public void setSpringDao(ISpringDao springDao) {
		this.springDao = springDao;
	}

	public IHQLDao getHqlDao() {
		return hqlDao;
	}

	public void setHqlDao(IHQLDao hqlDao) {
		this.hqlDao = hqlDao;
	}

	public IQbcDao getQbcDao() {
		return qbcDao;
	}

	public void setQbcDao(IQbcDao qbcDao) {
		this.qbcDao = qbcDao;
	}
	
	/* (non-Javadoc)
	 * @see com.tjsinfo.tjsoa.workflow.bo.ITaskInstanceBO#genZong(java.lang.Long, java.lang.Integer, java.lang.Integer)
	 */
	public PaginationSupport genZong(Long flowid,Integer first,Integer max){
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Taskinstance.class);
		detachedCriteria.add(Restrictions.eq("procinst", flowid));
		detachedCriteria.add(Restrictions.isNotNull("tjsUser.userId"));
		return qbcDao.findPageByCriteria(detachedCriteria, max, first);
		
	}
	
	public PaginationSupport genZongIsNull(Long flowid, Integer first,
			Integer max){
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Taskinstance.class);
		detachedCriteria.add(Restrictions.eq("procinst", flowid));
		return qbcDao.findPageByCriteria(detachedCriteria, max, first);
	}
	
	public Integer taskTjsUserIsNull(Long flowid){
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Taskinstance.class);
		detachedCriteria.add(Restrictions.eq("procinst", flowid));
		detachedCriteria.add(Restrictions.isNotNull("tjsUser.userId"));
		return  qbcDao.getCriteria(detachedCriteria).size();
	}
	
	
	public Long selectTaskFlowId(Long taskid) {
		// TODO Auto-generated method stub
		Taskinstance taskinstance = (Taskinstance) qbcDao.getObjectById(Taskinstance.class, taskid);
		return taskinstance.getProcinst();
	}
	
	public List<Taskinstance> selectAllTask(Long flowid){
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Taskinstance.class);
		detachedCriteria.add(Restrictions.eq("procinst", flowid));
		detachedCriteria.add(Restrictions.isNotNull("tjsUser.userId"));
		List<Taskinstance> list = qbcDao.getCriteria(detachedCriteria);
		return list;
		
	}
	
	public List<Taskinstance> selectAllTaskIsNull(Long flowid){
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Taskinstance.class);
		detachedCriteria.add(Restrictions.eq("procinst", flowid));
		List<Taskinstance> list = qbcDao.getCriteria(detachedCriteria);
		return list;
		
	}
	
	public List<Object[]>  selectAllUnfinshTask(){
		List list =  hqlDao.executeList("select id,name,actorid from Taskinstance where tjsUser.userId is not null and isopen = 1 order by id desc");
		
		return list;
		
	}
	
	/**
	 * 根据流程ID创建任务
	 * @param flowId 流程ID
	 * @param userId 用户ID
	 * @return
	 */
	public Boolean creatTask(Long flowId,String userId){
		WorkFlowTemplate workFlowTemplate = new WorkFlowTemplate();
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Taskinstance.class);
		detachedCriteria.add(Restrictions.eq("procinst", flowId));
		detachedCriteria.addOrder(Order.desc("id"));
		List<Taskinstance> taskinstanceList = qbcDao.getCriteria(detachedCriteria);
		Taskinstance taskinstance =  taskinstanceList.get(0);
		workFlowTemplate.createTaskInstance(taskinstance.getId(), userId);
		return true;
	}
	
	/**
	 * 根据流程名称查询异常任务
	 * @param proname
	 * @return
	 */
	public Integer selectYiChangTask(String proname){
		List<Integer> list = new ArrayList<Integer>();
		StringBuffer sql = new StringBuffer("SELECT COUNT(*) AS taskCount FROM dbo.JBPM_TASKINSTANCE AS taskinstance ");
		sql.append("JOIN dbo.JBPM_PROCESSINSTANCE processinstance ON  processinstance.ID_ = taskinstance.PROCINST_ ");
		sql.append("JOIN dbo.JBPM_PROCESSDEFINITION processdefinition ON processdefinition.ID_ = processinstance.PROCESSDEFINITION_ ");
		sql.append("LEFT JOIN dbo.t_xingzhengfawen_neirong AS xingzhengfawen ON xingzhengfawen.flowid = processinstance.ID_  ");
		sql.append("LEFT JOIN dbo.t_xingzhengshouwen_neirong AS xingzhengshouwen ON xingzhengshouwen.flowid = processinstance.ID_   ");
		sql.append("LEFT JOIN dbo.t_dangweifawen_neirong AS dangweifawen ON dangweifawen.flowid = processinstance.ID_  ");
		sql.append("LEFT JOIN dbo.t_dangweishouwen_neirong AS dangweishouwen ON dangweishouwen.flowid = processinstance.ID_    ");
		sql.append("LEFT JOIN dbo.t_tongzhifawen_neirong AS tongzhifawen ON tongzhifawen.flowid = processinstance.ID_    ");
		sql.append("WHERE taskinstance.ACTORID_ IS NULL AND processdefinition.NAME_ = ?  AND    (xingzhengfawen.biaoti IS NOT NULL OR xingzhengshouwen.laiwenzihao IS NOT NULL  OR dangweifawen.biaoti IS NOT NULL  OR dangweishouwen.laiwenzihao IS NOT NULL  OR tongzhifawen.biaoti IS NOT NULL) ");
		list = springDao.querySQL(sql.toString(), new Object[]{proname}, new RowMapper(){

			public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
				// TODO Auto-generated method stub
				return arg0.getInt("taskCount");
			}
			
		});
		return list.get(0);
	}
	
	/**
	 * 根据流程名称查询异常任务
	 * @param proname
	 * @return
	 */
	public Integer selectYiChangTask(){
		List<Integer> list = new ArrayList<Integer>();
		StringBuffer sql = new StringBuffer("SELECT COUNT(*) AS taskCount FROM dbo.JBPM_TASKINSTANCE AS taskinstance ");
		sql.append("JOIN dbo.JBPM_PROCESSINSTANCE processinstance ON  processinstance.ID_ = taskinstance.PROCINST_ ");
		sql.append("JOIN dbo.JBPM_PROCESSDEFINITION processdefinition ON processdefinition.ID_ = processinstance.PROCESSDEFINITION_ ");
		sql.append("LEFT JOIN dbo.t_xingzhengfawen_neirong AS xingzhengfawen ON xingzhengfawen.flowid = processinstance.ID_  ");
		sql.append("LEFT JOIN dbo.t_xingzhengshouwen_neirong AS xingzhengshouwen ON xingzhengshouwen.flowid = processinstance.ID_   ");
		sql.append("LEFT JOIN dbo.t_dangweifawen_neirong AS dangweifawen ON dangweifawen.flowid = processinstance.ID_  ");
		sql.append("LEFT JOIN dbo.t_dangweishouwen_neirong AS dangweishouwen ON dangweishouwen.flowid = processinstance.ID_    ");
		sql.append("LEFT JOIN dbo.t_tongzhifawen_neirong AS tongzhifawen ON tongzhifawen.flowid = processinstance.ID_    ");
		sql.append("WHERE taskinstance.ACTORID_ IS NULL   AND  (xingzhengfawen.biaoti IS NOT NULL OR xingzhengshouwen.laiwenzihao IS NOT NULL  OR dangweifawen.biaoti IS NOT NULL  OR dangweishouwen.laiwenzihao IS NOT NULL  OR tongzhifawen.biaoti IS NOT NULL) ");
		
		list = springDao.querySQL(sql.toString(), new Object[]{}, new RowMapper(){

			public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
				// TODO Auto-generated method stub
				return arg0.getInt("taskCount");
			}
			
		});
		return list.get(0);
	}
	
	/**
	 * 任务管理
	 * @return
	 */
	public List<Map<String, String>> taskAdmin(){
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		StringBuffer sql = new StringBuffer("SELECT taskinstance.ID_,taskinstance.NAME_,processinstance.ID_ AS processinstanceId , ");
		sql.append("processdefinition.NAME_  AS processdefinitionName, ");
		sql.append("xingzhengfawen.biaoti AS xingzhengfawenbiaoti,xingzhengshouwen.laiwenzihao AS xingzhengshouwenlaiwenzihao,dangweifawen.biaoti AS dangweifawenbiaoti, ");
		sql.append("dangweishouwen.laiwenzihao AS dangweishouwenlaiwenzihao,tongzhifawen.biaoti AS tongzhifawenbiaoti  ");
		sql.append("FROM dbo.JBPM_TASKINSTANCE AS taskinstance   ");
		sql.append("JOIN dbo.JBPM_PROCESSINSTANCE processinstance ON  processinstance.ID_ = taskinstance.PROCINST_ ");
		sql.append("JOIN dbo.JBPM_PROCESSDEFINITION processdefinition ON processdefinition.ID_ = processinstance.PROCESSDEFINITION_ ");
		sql.append("LEFT JOIN dbo.t_xingzhengfawen_neirong AS xingzhengfawen ON xingzhengfawen.flowid = processinstance.ID_  ");
		sql.append("LEFT JOIN dbo.t_xingzhengshouwen_neirong AS xingzhengshouwen ON xingzhengshouwen.flowid = processinstance.ID_   ");
		sql.append("LEFT JOIN dbo.t_dangweifawen_neirong AS dangweifawen ON dangweifawen.flowid = processinstance.ID_  ");
		sql.append("LEFT JOIN dbo.t_dangweishouwen_neirong AS dangweishouwen ON dangweishouwen.flowid = processinstance.ID_    ");
		sql.append("LEFT JOIN dbo.t_tongzhifawen_neirong AS tongzhifawen ON tongzhifawen.flowid = processinstance.ID_    ");
		sql.append("WHERE taskinstance.ACTORID_ IS NULL   AND  (xingzhengfawen.biaoti IS NOT NULL OR xingzhengshouwen.laiwenzihao IS NOT NULL  OR dangweifawen.biaoti IS NOT NULL  OR dangweishouwen.laiwenzihao IS NOT NULL  OR tongzhifawen.biaoti IS NOT NULL) ");
		list = springDao.querySQL(sql.toString(), new Object[]{}, new RowMapper(){

			public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
				// TODO Auto-generated method stub
				Map<String, String> map = new HashMap<String, String>();
				map.put("id", arg0.getString("ID_"));
				map.put("name", arg0.getString("NAME_"));
				map.put("processinstanceId", arg0.getString("processinstanceId"));
				if (arg0.getString("xingzhengfawenbiaoti") != null) {
					map.put("biaoti", arg0.getString("xingzhengfawenbiaoti"));
				}
				if (arg0.getString("xingzhengshouwenlaiwenzihao") != null) {
					map.put("biaoti", arg0.getString("xingzhengshouwenlaiwenzihao"));
				}
				if (arg0.getString("dangweifawenbiaoti") != null) {
					map.put("biaoti", arg0.getString("dangweifawenbiaoti"));
				}
				if (arg0.getString("dangweishouwenlaiwenzihao") != null) {
					map.put("biaoti", arg0.getString("dangweishouwenlaiwenzihao"));
				}
				if (arg0.getString("tongzhifawenbiaoti") != null) {
					map.put("biaoti", arg0.getString("tongzhifawenbiaoti"));
				}
				return map;
			}
			
		});
		return list;
	}
	
	/**
	 * 根据人员ID和流程名称查询异常任务
	 * @param username
	 * @param proname
	 * @return
	 */
	public Integer selectUnTask(String username, String proname){
		StringBuffer sql = new StringBuffer("SELECT COUNT(*) AS taskCount  FROM dbo.JBPM_TASKINSTANCE AS taskinstance  ");
		sql.append("JOIN dbo.JBPM_PROCESSINSTANCE AS processinstance ON taskinstance.PROCINST_ = processinstance.ID_ ");
		sql.append("JOIN dbo.JBPM_PROCESSDEFINITION AS processdefinition ON processdefinition.ID_ = processinstance.PROCESSDEFINITION_ ");
		sql.append("WHERE taskinstance.ACTORID_= ? AND taskinstance.ISOPEN_ = 1 AND taskinstance.ISSUSPENDED_= 0 AND processdefinition.NAME_ = ? ");
		List<Integer> list =  springDao.querySQL(sql.toString(), new Object[]{username,proname}, new RowMapper(){

			public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
				// TODO Auto-generated method stub
				return arg0.getInt("taskCount");
			}
			
		});
		
		return list.get(0);
	}
	
	/**
	 * 根据人员ID和流程名称查询任务返回流程实例ID
	 * @param username
	 * @param proname
	 * @return
	 */
	public List<Integer> selectUnTaskProId(String username, String proname){
		StringBuffer sql = new StringBuffer("SELECT processinstance.ID_  FROM dbo.JBPM_TASKINSTANCE AS taskinstance  ");
		sql.append("JOIN dbo.JBPM_PROCESSINSTANCE AS processinstance ON taskinstance.PROCINST_ = processinstance.ID_ ");
		sql.append("JOIN dbo.JBPM_PROCESSDEFINITION AS processdefinition ON processdefinition.ID_ = processinstance.PROCESSDEFINITION_ ");
		sql.append("WHERE taskinstance.ACTORID_= ? AND taskinstance.ISOPEN_ = 1 AND taskinstance.ISSUSPENDED_= 0 AND processdefinition.NAME_ = ? ");
		List<Integer> list =  springDao.querySQL(sql.toString(), new Object[]{username,proname}, new RowMapper(){

			public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
				// TODO Auto-generated method stub
				return arg0.getInt("ID_");
			}
			
		});
		return list;
	}
	
	/**
	 * 根据人员ID和变量名称查询变量值
	 * @param valuename
	 * @param processId
	 * @return
	 */
	public Integer selectValueBy(String valuename, Integer processId){
		StringBuffer sql = new StringBuffer("SELECT LONGVALUE_ AS  flowId  FROM dbo.JBPM_VARIABLEINSTANCE WHERE PROCESSINSTANCE_ = ? AND NAME_ = ?  ");
		List<Integer> list =  springDao.querySQL(sql.toString(), new Object[]{processId,valuename}, new RowMapper(){

			public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
				// TODO Auto-generated method stub
				return arg0.getInt("flowId");
			}
			
		});
		
		return list.get(0);
	}
	
	/**
	 * 根据流程ID查询当前任务
	 * @param processId 流程ID
	 * @return
	 */
	public String selectNodeByProcessId(Integer processId){
		StringBuffer sql = new StringBuffer("SELECT node.NAME_ AS node FROM dbo.JBPM_PROCESSINSTANCE AS processinstance  JOIN dbo.JBPM_TOKEN AS token  ");
		sql.append("ON processinstance.ROOTTOKEN_ = token.ID_ JOIN dbo.JBPM_NODE AS node  ");
		sql.append("ON node.ID_ =  token.NODE_  ");
		sql.append("WHERE processinstance.ID_ = ? ");
		List<String> list =  springDao.querySQL(sql.toString(), new Object[]{processId}, new RowMapper(){

			public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
				// TODO Auto-generated method stub
				return arg0.getString("node");
			}
			
		});
		if (list.size() <= 0 ) {
			return "封发";
		} else {
			return list.get(0);
		}
		
	}
	
	/**
	 * 根据流程ID查询某环节已结束任务
	 * @param processId 流程ID
	 * @return
	 */
		public PaginationSupport selectNodeTask(Long flowid,String node, Integer first,Integer max){
			DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Taskinstance.class);
			detachedCriteria.add(Restrictions.eq("procinst", flowid));
			detachedCriteria.add(Restrictions.eq("name", node));
			detachedCriteria.add(Restrictions.eq("version", 2));
			detachedCriteria.add(Restrictions.isNotNull("tjsUser.userId"));
			return qbcDao.findPageByCriteria(detachedCriteria, max, first);
			
		}
		
}
